package com.cool.config.springsecurity.login;

import cn.hutool.core.util.IdUtil;
import com.cool.bo.sysmanage.stuff.UserLoginBo;
import com.cool.po.sysmanagepo.RolePo;
import com.cool.po.sysmanagepo.StaffPo;
import com.cool.service.sysmanage.StaffService;
import com.cool.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户登录身份验证提供者
 *
 * @author Jiangmanman
 * @date 2020/07/31
 */
@Slf4j
public class UserLoginAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        UserLoginToken userLoginToken = (UserLoginToken)authentication;

        Object principalObj = userLoginToken.getPrincipal();
        if(Objects.isNull(principalObj)){
            throw new InternalAuthenticationServiceException("客户端未输入电话号码");
        }
        String username = principalObj.toString();

        Object validateObj = userLoginToken.getCredentials();
        if(Objects.isNull(validateObj)){
            throw new InternalAuthenticationServiceException("客户端未输入验证码");
        }
        String password = validateObj.toString();

        //检验账户名和密码是否存在
        System.out.println(this.getClass().getName() + "username = "+username + "password = "+password);

        StaffService staffService = SpringContextUtil.getBean(StaffService.class);

        StaffPo staffPo = staffService.selectByUsernameAndPassword(username,password);

        if(Objects.isNull(staffPo)){
            throw new InternalAuthenticationServiceException("用户名或密码输入错误");
        }
        //通过 staffId得到用户的所有角色
        List<RolePo> rolePos = staffService.queryAllRoleByStaffId(staffPo.getStaffId());
        List<String> collect = rolePos.stream().map(RolePo::getRoleName).collect(Collectors.toList());

        log.info("用户登录成功! 用户拥有角色为:"+collect.toString());

        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for(String role :collect){
            authorities.add(new SimpleGrantedAuthority(role));
        }

        UserLoginBo userLoginBo = new UserLoginBo();

        userLoginBo.setStaffId(staffPo.getStaffId());
        userLoginBo.setUsername(username);


        String str = "login";
        String simpleUUID = IdUtil.simpleUUID();

        userLoginBo.setToken(simpleUUID);
        userLoginBo.setTokenHead(str);


        return new UserLoginToken(userLoginBo,null,authorities);
    }

    /**
     * 判断入参 token 所匹配的 provider
     *
     * @param aClass 一个类
     * @return boolean
     * @author Jiangmanman
     * @date 2020/07/31
     */
    @Override
    public boolean supports(Class<?> aClass) {
        return aClass.isAssignableFrom(UserLoginToken.class);
    }
}
